package com.yanggeng.demo.beginnerguidedemo.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

import com.yanggeng.demo.beginnerguidedemo.utils.DeviceParams;

import java.util.LinkedHashMap;
import java.util.Map;

public class RadarView extends View {

    private int mCount = 6; // 多边形边数

    private int mLevelCount = 5; // 维度等级数，即有几个多边形

    private double angle; // 每个扇形的弧度，即圆的弧度/多边形变数，2π/mCount;

    private float mRadius; // 多边形半径

    private int mCenterX, mCenterY;

    private Map<String, Float> mValue = new LinkedHashMap<>(); // 数据集合，key为维度显示文字，value为维度大小

    private String[] mTexts;

    private float[] mValues;

    private float mMaxValue = 100f; // 数据最大值

    private Paint mMainPaint; // 多边形画笔

    private Paint mValuePaint; // 数据画笔

    private Paint mTextPaint; // 文字画笔

    public RadarView(Context context) {
        super(context);
        init(context);
    }

    public RadarView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RadarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        mMainPaint = new Paint();
        mMainPaint.setColor(Color.GRAY);
        mMainPaint.setStyle(Paint.Style.STROKE);
        mMainPaint.setStrokeWidth(2f);

        mValuePaint = new Paint();
        mValuePaint.setColor(Color.RED);
        mValuePaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mValuePaint.setStrokeWidth(2f);

        mTextPaint = new Paint();
        mTextPaint.setColor(Color.DKGRAY);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
        mTextPaint.setTextSize(DeviceParams.sp2px(context, 13));
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        mRadius = Math.min(w, h) / 2 * 0.9f;
        mCenterX = w / 2;
        mCenterY = h / 2;
        postInvalidate();
        super.onSizeChanged(w, h, oldw, oldh);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        angle = 2 * Math.PI / mCount;
        canvas.translate(mCenterX, mCenterY);
        drawPolygon(canvas);
        drawLines(canvas);
        drawValue(canvas);
        drawText(canvas);
    }

    private void drawPolygon(Canvas canvas) {

        Path path = new Path();
        float r = mRadius / mLevelCount;


        for (int i = 1; i < mLevelCount + 1; i++) {
            float currR = r * i;
            path.reset();
            for (int j = 0; j < mCount; j++) {
                if (j == 0) {
                    path.moveTo(currR, 0);
                } else {
                    float x = (float) (currR * Math.cos(angle * j));
                    float y = (float) (currR * Math.sin(angle * j));
                    path.lineTo(x, y);
                }
            }
            path.close();
            canvas.drawPath(path, mMainPaint);
        }
    }

    private void drawLines(Canvas canvas) {
        Path path = new Path();
        for (int i = 0; i < mCount; i++) {
            path.reset();
            path.moveTo(0, 0);
            float x = (float) (mRadius * Math.cos(angle * i));
            float y = (float) (mRadius * Math.sin(angle * i));
            path.lineTo(x, y);
            canvas.drawPath(path, mMainPaint);
        }
    }

    private void drawValue(Canvas canvas) {
        Path path = new Path();
        if (mValue.size() > 0) {
            for (int i = 0; i < mCount; i++) {
                float percent = mValues[i] / mMaxValue;
                float x = (float) (mRadius * Math.cos(angle * i) * percent);
                float y = (float) (mRadius * Math.sin(angle * i) * percent);
                if (i == 0) {
                    path.moveTo(x, 0);
                } else {
                    path.lineTo(x, y);
                }
                canvas.drawCircle(x, y, 10, mValuePaint);
            }
            mValuePaint.setStyle(Paint.Style.STROKE);
            canvas.drawPath(path, mValuePaint);
            mValuePaint.setStyle(Paint.Style.FILL);
            mValuePaint.setAlpha(127);
            canvas.drawPath(path, mValuePaint);
        }
    }

    private void drawText(Canvas canvas) {

        Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
        float fontHeight = fontMetrics.descent - fontMetrics.ascent;

        for (int i = 0; i < mCount; i++) {
            float x = (float) ((mRadius + fontHeight / 2) * Math.cos(angle * i));
            float y = (float) ((mRadius + fontHeight / 2) * Math.sin(angle * i));
            if (angle * i >= 0 && angle * i <= Math.PI / 2) {//第1象限
                y = (float) ((mRadius + fontHeight) * Math.sin(angle * i));
                float dis = mTextPaint.measureText(mTexts[i]);//文本长度
                if (angle * i == 0) {
                    canvas.drawText(mTexts[i], x + dis / 3, fontHeight / 4, mTextPaint);
                } else if (angle * i == Math.PI / 2) {
                     y = (float) ((mRadius + fontHeight / 2) * Math.sin(angle * i));
                    canvas.drawText(mTexts[i], x, y, mTextPaint);
                } else {
                    canvas.drawText(mTexts[i], x, y, mTextPaint);
                }
            } else if (angle * i >= 3 * Math.PI / 2 && angle * i <= Math.PI * 2) {//第4象限
                if (angle * i == 3 * Math.PI / 2) {
                    y = (float) ((mRadius + fontHeight / 4) * Math.sin(angle * i));
                }
                canvas.drawText(mTexts[i], x, y, mTextPaint);
            } else if (angle * i > Math.PI / 2 && angle * i <= Math.PI) {//第2象限
                float dis = mTextPaint.measureText(mTexts[i]);//文本长度
                y = (float) ((mRadius + fontHeight) * Math.sin(angle * i));
                if (angle * i == Math.PI) {
                    canvas.drawText(mTexts[i], x - dis / 4, fontHeight / 4, mTextPaint);
                } else {
                    canvas.drawText(mTexts[i], x, y, mTextPaint);
                }
            } else if (angle * i > Math.PI && angle * i < 3 * Math.PI / 2) {//第3象限
                canvas.drawText(mTexts[i], x, y, mTextPaint);
            }
        }
    }

    public void setData(LinkedHashMap<String, Float> data) {
        this.mValue.clear();
        this.mValue.putAll(data);
        mTexts = new String[data.size()];
        mValues = new float[data.size()];
        int i = 0;
        for (Map.Entry<String, Float> entry : data.entrySet()) {
            mTexts[i] = entry.getKey();
            mValues[i] = entry.getValue();
            i++;
        }
        invalidate();
    }

    public void setLevelCount(int levelCount) {
        this.mLevelCount = levelCount;
    }

    public void setCount(int count) {
        this.mCount = count;
    }
}
